// this Axios can be change to customized (with config) Axios.
import Axios from 'axios';
import Config from '../config/config';
import Bus from './bus';

// fixme for debugging
console.info('my-axios.js is loading.');

var vue; // the Vue constructor
var bus; // the 'bus' object
var tip; // the 'message' object

var baseUrl = Config.dataUrl || '';
var keyName = Config.auth.keyName || 'X-Auth-Token';
var loginUrl = Config.auth.loginUrl || 'Please-Set-Login-URL-Inside-Config-js';
var authType = Config.auth.type || 'token';

if (authType === 'token') {
    // todo conditionally constructing the 'token-axios' instance.
} else if (authType === 'cookie') {
    // todo conditionally constructing the 'cookie-axios' instance.
    // note remember to set 'withCredentials->true'
} else if (authType === 'tookie') {
    // todo conditionally construction the 'tookie-axios' instance.
    // note remember to set 'withCredentials->true'
} else {
    throw new Error('Please-Set-Correct-Auth-Type-Inside-Config-js');
}

// =============== axios: the token one (will be moved to a separate js file) ===================

window.addEventListener('unload', function() {
    console.info('window is to unload');
    if (bus.token) {
        sessionStorage.setItem('token', bus.token);
    }
});


var axios = Axios.create({
    baseURL: baseUrl,
});

axios.interceptors.request.use(function (config) {

    var token = bus.token;

    if (token) {
        console.log('put token into req --> %s', token);
        config.headers[keyName] = token;
    }

    // note always return config inside req interceptor!!
    return config;

}); // no error-handling in request interceptor

axios.interceptors.response.use(function (resp) {

    // 成功时不作处理
    return resp;
}, function (error) {

    // note error is complicated! You have to deal with it step by step.
    if (error.response) {

        var statusCode = error.response.status;
        console.log('status code => ' + statusCode);
        if (statusCode === 401) {

            bus.token = '';

            window.location.href = loginUrl;
            return Promise.reject('登录过期，请重新登录');

        } else if (statusCode === 403) {

            tip.error({
                content: '操作被阻止：没有权限，或者访问过于频繁',
                duration: 3,
            });
            return Promise.reject('操作被阻止：没有权限，或者访问过于频繁');

        } else if (statusCode === 404) {

            tip.warning({
                content: '[404 Not Found]你要找的页面不存在<br/>' + error.config.url,
                duration: 3,
            });
            return Promise.reject('404');

        } else if (statusCode === 500) {
            // note 返回的数据包是在response的data对象里面的
            // console.log(error.response);

            tip.error({
                content: `服务器开小差了：${error.response.data.message}`,
                duration: 3,
            });
            console.log('服务器开小差了： %s', error.response.data.message);
            return Promise.reject('服务器发生故障');
        } else {

            // todo global 'catch-all' error-handler
            tip.error({
                content: `发生了未知的错误： [${statusCode}] ${error.response.data.message}`,
                duration: 3,
            })
            return Promise.reject('发生了错误');
        }

    } else if (error.request) {

        console.log('request error: %o', error.request);

    } else {

        console.log('other error: %s', error.message);
    }

    console.log('error --> %o', error.config);
});

export default {
    // note put your getter/setter/tuner methods here. It can be called inside main.js

    // contract method for vue plugins
    install: function (Vue, options) {

        // fixme for debugging
        console.info('install() in my-axios.js is called.');

        vue = Vue;
        // note a singleton `$axios` is injected into every vue instance, so no need to import Axios again.
        Vue.prototype.$axios = axios;
        if (!Vue.prototype.$bus) {
            Vue.use(Bus);
        }
        bus = Vue.prototype.$bus;
        tip = Vue.prototype.$Message;

        // fixme for debugging
        console.info('ready to restore the token data.');
        var thatToken = sessionStorage.getItem('token');
        if (thatToken) {
            bus.token = thatToken;
        }
    }
};